package com.dave.gd.core.util;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.dave.gd.common.util.StringUtils;
import com.dave.gd.common.util.spring.ApplicationContextUtil;
import com.dave.gd.core.base.entity.IAttrSpec;
import com.dave.gd.core.base.entity.IAttrValue;
import com.dave.gd.core.base.entity.ISysClass;
import com.dave.gd.core.base.service.ISysClassRepositoryService;

/**
 * 
 * MetaProvider
 * .
 * @author hehuang
 * @date 2014年11月25日
 *
 */
public class MetaProvider {
    
    //	@Autowired
    //	@Qualifier("sysClassRepositoryService")
    private static ISysClassRepositoryService sysClassRepositoryService = ApplicationContextUtil
                                                                            .getBean("sysClassRepositoryService");
    
    /**
     *  缓存数据：基于javaCode
     */
    private static Map<String, ISysClass>     mapClassByEntityName      = new ConcurrentHashMap<String, ISysClass>(
                                                                            200);
    /**
     * 缓存数据：基于sysClassId
     */
    private static Map<Long, ISysClass>       mapClassByEntityId        = new ConcurrentHashMap<Long, ISysClass>(
                                                                            200);
    
    /**
     * 方法功能: 根据 实体名称，如：Party 获取 元数据配置。
     * 
     * @param strEntityName
     * @return ISysClass
     * @author: 
     * @修改记录： 
     */
    public static ISysClass getEntityByName(String strEntityName) {
        if (StringUtils.isNullOrEmpty(strEntityName))
            return null;
        
        ISysClass entity = mapClassByEntityName.get(strEntityName);
        
        if (entity != null || mapClassByEntityName.containsKey(strEntityName)) {
            return entity;
        }
        
        entity = sysClassRepositoryService.getEntityByName(strEntityName);
        
        if (entity == null) {
            // sync map 不能缓存null对象，直接返回
            // mapClassByEntityName.put(strEntityName, null);
            // log
            // logger.info("实体元数据未配置:" + strEntityName);
            return null;
            
        }
        
        mapClassByEntityName.put(strEntityName, entity);
        mapClassByEntityId.put(entity.getId(), entity);
        
        return entity;
    }
    
    public static ISysClass getEntityById(Long id) {
        if (id == null) {
            return null;
        }
        
        if (mapClassByEntityId.containsKey(id)) {
            return mapClassByEntityId.get(id);
        }
        
        ISysClass sysClass = sysClassRepositoryService.getEntityById(id);
        
        if (sysClass == null) {
            // sync map不能缓存null对象
            return null;
        }
        
        mapClassByEntityName.put(sysClass.getJavaCode(), sysClass);
        mapClassByEntityId.put(id, sysClass);
        
        return sysClass;
    }
    
    public static List<IAttrValue> getAttrValues(String className, String propertyName) {
        ISysClass sysClass = MetaProvider.getEntityByName(className);
        return getAttrValues(sysClass, propertyName);
    }
    
    public static List<IAttrValue> getAttrValues(ISysClass sysClass, String propertyName) {
        if (sysClass != null) {
            return sysClass.getAttrValues(propertyName);
        }
        return null;
    }
    
    public static List<IAttrValue> getAttrValues(String className, Long attrId) {
        ISysClass sysClass = MetaProvider.getEntityByName(className);
        if (sysClass == null) {
            return null;
        }
        
        IAttrSpec attrSpec = sysClass.getAttrSpecById(attrId);
        if (attrSpec == null) {
            return null;
        }
        return sysClass.getAttrValues(attrSpec.getJavaCode());
    }
    
    public static IAttrSpec getAttrSpec(String className, String propertyName) {
        ISysClass sysClass = MetaProvider.getEntityByName(className);
        if (sysClass == null) {
            return null;
        }
        return sysClass.getAttrSpecByCode(propertyName);
    }
    
    public static IAttrSpec getAttrSpecByAttrCd(String className, String attrCd) {
        ISysClass sysClass = MetaProvider.getEntityByName(className);
        if (sysClass == null || StringUtils.isNullOrEmpty(attrCd)) {
            return null;
        }
        List<IAttrSpec> attrs = sysClass.getAttrSpecs();
        for (IAttrSpec attr : attrs) {
            if (attr != null && attrCd.equals(attr.getAttrCd())) {
                return attr;
            }
        }
        return null;
    }
    
    public static String getAttrNameByValue(String className, String propertyName, String value) {
        List<IAttrValue> attrValues = MetaProvider.getAttrValues(className, propertyName);
        if (attrValues != null && attrValues.size() > 0) {
            for (IAttrValue attrValue : attrValues) {
                if (attrValue != null && attrValue.getAttrValue() != null
                    && attrValue.getAttrValue().equals(value)) {
                    return attrValue.getAttrValueName();
                }
            }
        }
        return "";
        
    }
    
    public static void clear() {
        mapClassByEntityName = new ConcurrentHashMap<String, ISysClass>(200);
        mapClassByEntityId = new ConcurrentHashMap<Long, ISysClass>(200);
    }
    
    public static String getAttrValueByName(String className, String propertyName,
        String attrValueName) {
        List<IAttrValue> attrValues = MetaProvider.getAttrValues(className, propertyName);
        if (attrValues != null && attrValues.size() > 0) {
            for (IAttrValue attrValue : attrValues) {
                if (attrValue != null && attrValue.getAttrValueName() != null
                    && attrValue.getAttrValueName().equals(attrValueName)) {
                    return attrValue.getAttrValue();
                }
            }
        }
        
        return "";
    }
    
    public static IAttrValue getAttrValueByValue(String className, String propertyName,
        String attrValue) {
        List<IAttrValue> attrValues = MetaProvider.getAttrValues(className, propertyName);
        if (attrValues != null && attrValues.size() > 0) {
            for (IAttrValue value : attrValues) {
                if (value != null && value.getAttrValue() != null
                    && value.getAttrValue().equals(attrValue)) {
                    return value;
                }
            }
        }
        return null;
    }
    
    public static IAttrValue getAttrValueByValueId(Long attrId, Long attrValueId) {
        IAttrSpec attrSpec = sysClassRepositoryService.getAttrSpecById(attrId);
        if (attrSpec == null) {
            return null;
        }
        
        List<IAttrValue> attrValues = attrSpec.getAttrValues();
        if (attrValues != null && attrValues.size() > 0) {
            for (IAttrValue attrValue : attrValues) {
                if (attrValue != null && attrValue.getAttrValueId() != null
                    && attrValue.getAttrValueId().equals(attrValueId)) {
                    return attrValue;
                }
            }
        }
        return null;
    }
    
    private MetaProvider() {
    }
    
}
